﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using System.Net;
using System.Text.RegularExpressions;

using Winista.Text.HtmlParser;
using Winista.Text.HtmlParser.Lex;
using Winista.Text.HtmlParser.Util;
using Winista.Text.HtmlParser.Tags;
using Winista.Text.HtmlParser.Filters;

namespace GetWord
{
    public partial class Main : Form
    {
        public Main()
        {
            InitializeComponent();
        }

        private void btStart_Click(object sender, EventArgs e)
        {
            Site s1 = new Site();
            s1.Name = "百度";
            s1.Url = "http://www.longwiki.net/%E5%B7%AE";
            s1.RegexPattern = @"(?is)<div\s+id=""bodyContent"">(?><div[^>]*>(?<o>)|</div>(?<-o>)|(?:(?!</?div\b).)*)*(?(o)(?!))</div>";
            s1.Encoding = Encoding.UTF8;
            s1.UrlTemp = "{0}";

            using (WebClient wc1 = new WebClient())
            {
                wc1.Encoding = s1.Encoding;
                wc1.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wc1_DownloadStringCompleted);
                wc1.DownloadStringAsync(new Uri(s1.Url), s1);
            }

            





        }

        void wc1_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
        {
            Site item = e.UserState as Site;
            string text = e.Result;
            string t1 = StripHTMLTest.StripHTML(text);
            string t2 = StripHTMLTest.DelHTML(text);
            string html = "";
            MatchCollection mc = Regex.Matches(text, item.RegexPattern, RegexOptions.Multiline);
            if (mc.Count > 0)
            {
                foreach (Match m in mc)
                {
                    if (m.Success)
                    {
                        html = m.Groups[0].Value;
                    }
                }
            }
            

            #region 获得网页的html
            
            //try
            //{

            //    string url = @"http://www.longwiki.net/%E5%B7%AE";
            //    System.Net.WebClient aWebClient = new System.Net.WebClient();
            //    aWebClient.Encoding = System.Text.Encoding.Default;
            //    html = aWebClient.DownloadString(url);
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message);
            //}
            #endregion

            #region 分析网页html节点
            Lexer lexer = new Lexer(html);
            Parser parser = new Parser(lexer);
            NodeList htmlNodes = parser.Parse(null);
            this.treeView1.Nodes.Clear();
            this.treeView1.Nodes.Add("root");
            TreeNode treeRoot = this.treeView1.Nodes[0];
            for (int i = 0; i < htmlNodes.Count; i++)
            {
                this.RecursionHtmlNode(treeRoot, htmlNodes[i], false);
            }

            #endregion
 
            //TreeNode tnRet = null;

            //foreach (TreeNode tn in this.treeView1.Nodes)
            //{

            //    tnRet = FindNode(tn, "BODY");

            //    if (tnRet != null)
            //    {
            //        string xxx = tnRet.Text;
            //    }

            //}

            

        }

        private TreeNode FindNode(TreeNode tnParent, string strValue)
        {

            if (tnParent == null) return null;



            if (tnParent.Text == strValue) return tnParent;

            else if (tnParent.Nodes.Count == 0) return null;



            TreeNode tnCurrent, tnCurrentPar;



            //Init node

            tnCurrentPar = tnParent;

            tnCurrent = tnCurrentPar.FirstNode;



            while (tnCurrent != null && tnCurrent != tnParent)
            {

                while (tnCurrent != null)
                {

                    if (tnCurrent.Text == strValue) return tnCurrent;

                    else if (tnCurrent.Nodes.Count > 0)
                    {

                        //Go into the deepest node in current sub-path

                        tnCurrentPar = tnCurrent;

                        tnCurrent = tnCurrent.FirstNode;

                    }

                    else if (tnCurrent != tnCurrentPar.LastNode)
                    {

                        //Goto next sible node

                        tnCurrent = tnCurrent.NextNode;

                    }

                    else

                        break;

                }



                //Go back to parent node till its has next sible node

                while (tnCurrent != tnParent && tnCurrent == tnCurrentPar.LastNode)
                {

                    tnCurrent = tnCurrentPar;

                    tnCurrentPar = tnCurrentPar.Parent;

                }



                //Goto next sible node

                if (tnCurrent != tnParent)

                    tnCurrent = tnCurrent.NextNode;

            }

            return null;

        }

        private TreeNode FindNode2(TreeNode tnParent, string strValue)
        {

            if (tnParent == null) return null;

            if (tnParent.Text == strValue) return tnParent;



            TreeNode tnRet = null;

            foreach (TreeNode tn in tnParent.Nodes)
            {

                tnRet = FindNode2(tn, strValue);

                if (tnRet != null) break;

            }

            return tnRet;

        }







        private void btnParser_Click(object sender, EventArgs e)
        {

        }

        private void RecursionHtmlNode(TreeNode treeNode, INode htmlNode, bool siblingRequired)
        {
            if (htmlNode == null || treeNode == null) return;

            TreeNode current = treeNode;
            TreeNode content ;
            //current node
            if (htmlNode is ITag)
            {
                ITag tag = (htmlNode as ITag);
                if (!tag.IsEndTag())
                {
                    string nodeString = tag.TagName;
                    if (tag.Attributes != null && tag.Attributes.Count > 0)
                    {
                        if (tag.Attributes["ID"] != null)
                        {
                            nodeString = nodeString + " { id=\"" + tag.Attributes["ID"].ToString() + "\" }";
                        }
                        if (tag.Attributes["HREF"] != null)
                        {
                            nodeString = nodeString + " { href=\"" + tag.Attributes["HREF"].ToString() + "\" }";
                        }
                    }
                    
                    current = new TreeNode(nodeString);
                    treeNode.Nodes.Add(current);
                }
            }

            //获取节点间的内容
            if (htmlNode.Children != null && htmlNode.Children.Count > 0)
            {
                this.RecursionHtmlNode(current, htmlNode.FirstChild, true);
                content = new TreeNode(htmlNode.FirstChild.GetText());
                treeNode.Nodes.Add(content);
            }

            //the sibling nodes
            if (siblingRequired)
            {
                INode sibling = htmlNode.NextSibling;
                while (sibling != null)
                {
                    this.RecursionHtmlNode(treeNode, sibling, false);
                    sibling = sibling.NextSibling;
                }
            }
        }
        private void AddUrl()
        {
            //CBUrl.Items.Add("http://www.hao123.com");
            //CBUrl.Items.Add("http://www.sina.com");
            //CBUrl.Items.Add("http://www.heuet.edu.cn");
        }

    }

    public class Site
    {
        public string Name { get; set; }
        public string Url { get; set; }
        public string RegexPattern { get; set; }
        public Encoding Encoding { get; set; }
        public string UrlTemp { get; set; }
        public string[] Keys { get; set; }
        public int Numbers { get; set; }
    }


    ///提取HTML代码中文字的C#函数
    ///   <summary>
    ///   去除HTML标记
    ///   </summary>
    ///   <param   name="strHtml">包括HTML的源码   </param>
    ///   <returns>已经去除后的文字</returns>

    public class StripHTMLTest
    {
        //public   static   void   Main(){
        //    string   s=StripHTML("<HTML><HEAD><TITLE>中国石龙信息平台</TITLE></HEAD><BODY>faddfs龙信息平台</BODY></HTML>");
        //Console.WriteLine(s);
        // }
        public static string StripHTML(string strHtml)
        {
            string[] aryReg ={
                              @"<script[^>]*?>.*?</script>",
                              @"<(\/\s*)?!?((\w+:)?\w+)(\w+(\s*=?\s*(([""'])(\\[""'tbnr]|[^\7])*?\7|\w+)|.{0})|\s)*?(\/\s*)?>",
                              @"([\r\n])[\s]+",
                              @"&(quot|#34);",
                              @"&(amp|#38);",
                              @"&(lt|#60);",
                              @"&(gt|#62);",
                              @"&(nbsp|#160);",
                              @"&(iexcl|#161);",
                              @"&(cent|#162);",
                              @"&(pound|#163);",
                              @"&(copy|#169);",
                              @"&#(\d+);",
                              @"-->",
                              @"<!--.*\n"
                            };
            string[] aryRep =   {
                                "",
                                "",
                                "",
                                "\"",
                                "&",
                                "<",
                                ">",
                                "   ",
                                "\xa1",//chr(161),
                                "\xa2",//chr(162),
                                "\xa3",//chr(163),
                                "\xa9",//chr(169),
                                "",
                                "\r\n",
                                ""
                              };

            string newReg = aryReg[0];
            string strOutput = strHtml;
            for (int i = 0; i < aryReg.Length; i++)
            {
                Regex regex = new Regex(aryReg[i], RegexOptions.IgnoreCase);
                strOutput = regex.Replace(strOutput, aryRep[i]);
            }
            strOutput.Replace("<", "");
            strOutput.Replace(">", "");
            strOutput.Replace("\r\n", "");
            return strOutput;
        }

        public static string DelHTML(string Htmlstring)//将HTML去除
        {
            #region
            //删除脚本
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"<script[^>]*?>.*?</script>", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            //删除HTML
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"<(.[^>]*)>", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"([\r\n])[\s]+", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"-->", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"<!--.*", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            //Htmlstring =System.Text.RegularExpressions. Regex.Replace(Htmlstring,@"<A>.*</A>","");
            //Htmlstring =System.Text.RegularExpressions. Regex.Replace(Htmlstring,@"<[a-zA-Z]*=\.[a-zA-Z]*\?[a-zA-Z]+=\d&\w=%[a-zA-Z]*|[A-Z0-9]","");
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(quot|#34);", "\"", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(amp|#38);", "&", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(lt|#60);", "<", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(gt|#62);", ">", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(nbsp|#160);", " ", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(iexcl|#161);", "\xa1", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(cent|#162);", "\xa2", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(pound|#163);", "\xa3", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&(copy|#169);", "\xa9", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring = System.Text.RegularExpressions.Regex.Replace(Htmlstring, @"&#(\d+);", "", System.Text.RegularExpressions.RegexOptions.IgnoreCase);
            Htmlstring.Replace("<", "");
            Htmlstring.Replace(">", "");
            Htmlstring.Replace("\r\n", "");
            //Htmlstring=HttpContext.Current.Server.HtmlEncode(Htmlstring).Trim();
            #endregion
            return Htmlstring;
        }
    }

     

}
